<?php

use LucaDegasperi\OAuth2Server\Authorizer;

class CommonController extends ApiController
{

    const CSI_URL = 'http://m.chinashippinginfo.net';

    const CSP_URL = 'http://m.csapchina.com';

    const WEB_FLAG = 2;

    protected $origin = '';

    protected $uid = null;

    protected $uip = '';

    protected $content = '';

    protected $insertId;

    protected $flag = 2;

    /**
     * 存储实例化的数据模型model
     * 其中数组的值 \Illuminate\Database\Query\Builder
     *
     * @var array
     */
    protected $models = array();

    public function __construct(Authorizer $authorizer)
    {
        parent::__construct($authorizer);
    }

    /**
     * 文章固定信息返回
     *
     * @return object
     */
    protected function article()
    {
        return $this->dbRepository('sqlsrv', 'articles')
            ->select('article_id as id', 'article_title as title', 'article_logo as thumbnail_url', 'article_writer as origin', 'article_whoadd as author', 'article_addtime as created_at')
            ->where('article_active', 1);
    }

    protected function getArticleById($id)
    {
        $key = 'articles/'.$id;
        if (Cache::has($key)) {
            return Cache::get($key);
        }

        $article = $this->article()
            ->where('article_id', $id)
            ->first();
        // 缓存文章内容
        $minutes = 7*24*60;
        Cache::put($key, $article, $minutes);

        return $article;
    }

    /**
     * 用户固定信息返回
     *
     * @return object
     */
    protected function user()
    {
        return DB::table('user')
            ->select('id', 'display_name as name', 'avatar_url', 'email', 'gender', 'company');
    }

    /**
     * [checkUserStar description]
     * @param  string $uid       用户id
     * @param  string $articleId 文章id
     * @return boolean
     */
    protected function checkUserStar($uid, $articleId)
    {
        $this->models['star'] = DB::table('star');

        return $this->models['star']
            ->where('user_id', $uid)
            ->where('article_id', $articleId)
            ->exists();
    }

    protected function checkUserFavour($uid, $commentId)
    {
        return DB::table('favour')
            ->where('user_id', $uid)
            ->where('article_comment_id', $commentId)
            ->where('flag', $this->flag)
            ->exists();
    }

    /**
     * 获取用户 ID
     * 用户未登录返回空字符串 ''
     * 登录用户返回用户 ID
     *
     * @return string
     */
    protected function getUid()
    {
        return (! $this->accessToken) ? '' : ($this->getownerId());
    }

    /**
     * 根据 Access Token 获取用户 ID
     *
     * @return string
     */
    protected function getOwnerId()
    {
        $this->authorizer->validateAccessToken();

        return $this->authorizer->getResourceOwnerId();
    }

    protected function getOwner()
    {
        if ($this->uid !== null) {
            // 获取用户的信息
            return $this->getUserInfo();
        }
        // 返回匿名用户信息
        return MultiplexController::anonymousUser($this->uip);
    }

    /**
     * 获取本地用户信息
     *
     * @return object stdClass
     */
    protected function getUserInfo()
    {
        $user = $this->user()->find($this->uid);

        $user->avatar_url = $this->prependAvatarPrefix($user->avatar_url);

        return $user;
    }

    private function getUser()
    {
        return DB::connection('sqlsrv')->table('User')
            ->select('User_ID as id', 'User_Name as name', 'User_Photo as avatar_url', 'User_Email as email', 'User_Sex as gender', 'User_Company as company')
            ->where('User_ID', $this->uid)
            ->first();
    }

    protected function prependAvatarPrefix($avatarUrl)
    {
        // 网站域名
        $tld = Request::root();

        return $tld.$avatarUrl;
    }

    /**
     * [dbRepository description]
     * @param  string $connection 数据库连接名
     * @param  string $name       数据库仓库名（表名或集合名）
     * @return object
     */
    protected function dbRepository($connection, $name)
    {
        return DB::connection($connection)->table($name);
    }

    /**
     * [processCommentResponse description]
     * @param  array $comments
     * @return todo
     */
    protected function processCommentResponse($comments)
    {
        foreach ($comments as $comment) {
            $this->commentId = $comment->id;

            $comment->is_favoured = $this->isFavoured($comment->favours);

            $comment->flag = self::WEB_FLAG;

            $this->uid = $comment->user_id;
            $this->uip = $comment->user_ip;
            $comment->user = $this->getOwner();

            $comment->replies = $this->getReply();

            unset($comment->user_id, $comment->user_ip);
        }

        return $comments;
    }

    protected function isFavoured($quantity)
    {
        if ($quantity == 0) {
            return false;
        }

        if (!$this->accessToken) {
            return false;
        }

        $uid = $this->getOwnerId();

        $this->flag = 2;

        return $this->checkUserFavour($uid, $this->commentId);
    }

    protected function checkIsFavoured($favours, $commentId, $flag)
    {
        if ($favours == 0) {
            return false;
        }

        if (! $this->accessToken) {
            return false;
        }

        $uid = $this->getOwnerId();

        $this->flag = $flag;

        return $this->checkUserFavour($uid, $commentId);
    }

    protected function getReply()
    {
        $replies = DB::table('reply')
            ->select('id', 'article_comment_id', 'user_id', 'user_ip', 'created_at', 'content')
            ->where('flag', self::WEB_FLAG)
            ->where('article_comment_id', $this->commentId)
            ->latest('created_at')
            ->take(2)
            ->get();

        foreach ($replies as $reply) {
            $this->uid = $reply->user_id;
            $this->uip = $reply->user_ip;

            $reply->user = $this->getOwner();

            unset($reply->article_comment_id, $reply->user_id, $reply->user_ip);
        }

        return $replies;
    }

    protected function getAllTagName()
    {
        $key = 'tag_names';
        if (Cache::has($key)) {
            return Cache::get($key);
        }

        $tagArr = DB::connection('secondly')->table('tag')->lists('name');
        $minutes = 24*60;
        Cache::put($key, $tagArr, $minutes);

        return $tagArr;
    }

    /**
     * [getTagStr description]
     * @param  [type] $str [description]
     * @return string
     */
    protected function getTagStr($str)
    {
        $tagArr = $this->getAllTagName();

        $tag = array();
        foreach ($tagArr as $value) {
            preg_match('#'.$value.'#', $str, $matches);
            if ($matches) {
                $tag[] = $matches[0];
            }
        }

        return implode(',', $tag);
    }

    protected function getTagFromComment($id)
    {
        $tagArr = DB::table('article_comment')
            ->where('article_id', '=', $id)
            ->where('tag', '<>', '')
            ->latest('created_at')
            ->take(8)
            ->lists('tag');

        return array_flip(array_count_values($tagArr));
    }

    protected function getTagForComment($id)
    {
        $tagArr = $this->getTagFromComment($id);

        ksort($tagArr);
        // 回传数组中最后一个元素
        return last($tagArr) ?: '';
    }

    protected function getTagForArticle($id)
    {
        $tagArr = $this->getTagFromComment($id);

        $resultArr = array_filter($tagArr, function($value)
        {
            return ! strpos($value, ',');
        });

        ksort($resultArr);
        // 回传数组中最后一个元素
        return last($resultArr) ?: '';
    }

    protected function getCsiComment($tag)
    {
        $this->placeholder = ['secondly', 'article_comment', '1', self::CSI_URL];

        return $this->getPlaceholderComment($tag);
    }

    protected function getCspComment($tag)
    {
        $this->placeholder = ['fourthly', 'journal_comment', '3', self::CSP_URL];

        return $this->getPlaceholderComment($tag);
    }

    protected function getPlaceholderComment($tag)
    {
        list($connection, $table, $webFlag) = $this->placeholder;

        $comments = DB::connection($connection)
            ->table($table)
            ->where('tag', '=', $tag)
            ->latest('created_at')
            ->take(1)
            ->get();
        foreach ($comments as $comment) {
            $comment->flag        = $webFlag;
            $comment->is_favoured = $this->checkIsFavoured($comment->favours, $comment->id, $webFlag);
            $comment->replies     = $this->getPlaceholderCommentReply($comment->id);
            $comment->user        = $this->getUserByFlag($comment->user_id, $comment->user_ip);
            // release some var
            unset($comment->user_id, $comment->user_ip, $comment->updated_at);
        }

        return $comments;
    }

    protected function getPlaceholderCommentReply($commentId)
    {
        list($connection, $table, $flag, $urlPrefix) = $this->placeholder;

        $replies = DB::connection($connection)
            ->table('reply')
            ->where($table.'_id', '=', $commentId)
            ->where('flag', '=', $flag)
            ->latest('created_at')
            ->take(1)
            ->get();
        foreach ($replies as $reply) {
            $reply->user = $this->getUserByFlag($reply->user_id, $reply->user_ip);
            // release some var
            unset($reply->user_id, $reply->user_ip, $reply->updated_at);
        }

        $currentReply = $this->getCurrentReply($commentId);

        return array_merge($currentReply, $replies);
    }

    protected function getCurrentReply($commentId)
    {
        list(, , $flag) = $this->placeholder;

        $replies = DB::table('reply')
            ->where('article_comment_id', '=', $commentId)
            ->where('flag', '=', $flag)
            ->latest('created_at')
            ->take(1)
            ->get();
        foreach ($replies as $reply) {
            $this->uid   = $reply->user_id;
            $this->uip   = $reply->user_ip;
            $reply->user = $this->getOwner();
        }

        return $replies;
    }

    protected function getJournalById($id)
    {
        return DB::connection('fifthly')
            ->table('qikan')
            ->find($id, ['id', 'qname as origin']);
    }

    protected function getCsiArticle($id, $imageFlag)
    {
        if ($imageFlag === 1) {
            $article = MultiplexController::getCsiImageNewsBrief($id);
        } else {
            $article = MultiplexController::getCsiArticleBrief($id);
        }

        return [
            'id'    => $article->Id,
            'orign' => $article->Source ?: 'CSI',
        ];
    }

    protected function getUserByFlag($uid, $ip)
    {
        list(, , $flag, $urlPrefix) = $this->placeholder;

        $functionName = ($flag === '1')
            ? 'getCsiUser' : 'getCspUser';

        $user = $this->{$functionName}($uid, $ip);
        if (! starts_with($user->avatar_url, 'http')) {
            $user->avatar_url = $urlPrefix.$user->avatar_url;
        }

        return $user;
    }

    protected function getCsiUser($uid, $ip)
    {
        if ($uid === null) {
            return MultiplexController::anonymousUser($ip);
        }

        return MultiplexController::getUser($uid);
    }

    protected function getCspUser($uid, $ip)
    {
        if ($uid === null) {
            return MultiplexController::anonymousUser($ip);
        }

        return DB::connection('fifthly')
            ->table('user')
            ->find($uid, ['name', 'avatar_url']);
    }

    protected function updateCommentFavours($commentId)
    {
        list($this->connection, $this->table) = $this->getConnection();

        $delta = ($this->operator === '+') ? 1 : -1;

        if ($delta === -1) {
            // check the delta is valid
            // if it is neccssary to decrement
            // if the current favours of comment is zero
            // it is not nessary to decrement
            $delta = $this->isValid($commentId);
        }

        // 如果更新的变化量为 0
        // 直接退出，不做处理
        if ($delta === 0) {
            return;
        }

        DB::connection($this->connection)
            ->table($this->table)
            ->where('id', '=', $commentId)
            // increment 也可以来减少
            ->increment('favours', $delta, array('updated_at' => date('Y-m-d H:i:s')));
    }

    protected function getConnection()
    {
        switch ($this->flag) {
            case '1':
                $connection = 'secondly';
                $table = 'article_comment';
                break;
            case '2':
                $connection = 'mysql';
                $table = 'article_comment';
                break;
            case '3':
                $connection = 'fourthly';
                $table = 'journal_comment';
                break;
            default:
                # code...
                break;
        }

        return [$connection, $table];
    }

    protected function isValid($commentId)
    {
        $favours = DB::connection($this->connection)
            ->table($this->table)
            ->where('id', '=', $commentId)
            ->pluck('favours');

        if ($favours > 0) {
            return -1;
        }

        return 0;
    }

}